﻿using System;
using biz.ritter.javapi.io;
using biz.ritter.javapi.lang;
using Nofs.Net.Common.Interfaces.Domain;
using Nofs.Net.Domain.Impl;
using Nofs.Net.Fuse.Impl;

namespace Nofs.Net.Execution
{
    public class ExecutionServerHandler
    {
        private PathTranslator _translator;
        private LogManager _logger;
        private static String _separatorChar = "" + File.separatorChar;

        public ExecutionServerHandler(
                PathTranslator translator,
                LogManager logger)
        {
            _translator = translator;
            _logger = logger;
        }

        public int Handle(String xml) //throws Exception 
        {
            _logger.LogInfo("received packet: ");
            _logger.LogInfo(xml);
            return Handle(new MethodInvocation(xml));
        }

        private Object[] GetTranslatedParameters(MethodInvocation method) //throws Exception 
        {
            Object[] args = new Object[method.GetParameters().size()];
            for (int i = 0; i < args.Length; i++)
            {
                IMethodParameter parameter = method.GetParameters().get(i);
                if (parameter.IsComplex())
                {
                    String parameterPath = ExternalToInternalPathTranslator.Translate(method.GetPwd(), parameter.GetValue());
                    IFileObject valueFileObj = _translator.TranslatePath(parameterPath);
                    if (valueFileObj != null)
                    {
                        args[i] = valueFileObj.GetObject();
                    }
                    else
                    {
                        args[i] = null;
                    }
                }
                else
                {
                    args[i] = parameter.ConvertToValue();
                }
            }
            return args;
        }

        private String CombinePaths(String part1, String part2)
        {
            if (!part1.EndsWith(_separatorChar) && !part2.startsWith(_separatorChar))
            {
                return part1 + _separatorChar + part2;
            }
            return part1 + part2;
        }

        public int Handle(MethodInvocation method)// throws Exception 
        {
            String executablePath = ExternalToInternalPathTranslator.Translate(method.GetPath());
            executablePath = CombinePaths(executablePath, method.MethodName());
            IFileObject executable = _translator.TranslatePath(executablePath);
            if (executable == null)
            {
                _logger.LogInfo("path '" + executablePath + "' does not exist in the FS");
                return 1;
            }
            else if (!executable.HasMethod())
            {
                _logger.LogInfo("path '" + executablePath + "' is not executable");
                return 1;
            }
            if (executable.GetMethod().getReturnType() == typeof(int).getClass())
            {
                Object value = executable.GetMethod().invoke(executable.GetObject(), GetTranslatedParameters(method));
                return ((Integer)value).intValue();
            }
            else
            {
                executable.GetMethod().invoke(executable.GetObject(), GetTranslatedParameters(method));
                return 0;
            }
        }
    }

}
